package com.yuqih.common.dto;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Arrays;

import org.apache.commons.lang3.StringUtils;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

public class ModelProxy {

	@SuppressWarnings("unchecked")
	public static <T> T createProxyInstance(Class<T> clazz, Method[] methods, 
			T instance, T delegated) {
		Enhancer enhancer = new Enhancer();
		enhancer.setClassLoader(clazz.getClassLoader());

		enhancer.setSuperclass(clazz);
		enhancer.setCallback(new Interceptor(methods, instance,delegated));
		// enhancer.setUseCache(true); 这个是默认true的，这样对同一个类不会多次生成Class

		return (T) enhancer.create();
	}
	
	private static class Interceptor implements MethodInterceptor, Serializable {

		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		private Method[] methods;
		private final Object instance;
		private final Object delegated;
		
		Interceptor(Method[] methods, Object instance, Object delegated) {
			this.instance = instance;
			this.methods = methods;
			this.delegated = delegated;
		}

		@Override
		public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
						
			Method  m =  findMethod(method);
			if (m != null) {
				return proxy.invoke(delegated, args);
			}
			
			return proxy.invoke(instance, args);
		}
		
		private Method findMethod(Method method) {
			
			for (Method m : methods) {
				if (StringUtils.equals(method.getName(), m.getName()) 
						&& Arrays.equals(method.getParameterTypes(), m.getParameterTypes()) ) {
					return m;
				}
			}
			return null;
		}

	}
	
	
}
